﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LeastSquares.Function
{
    /// <summary>
    /// 对已知数据计算，得到最小二乘法模型
    /// </summary>
    public class Model
    {
        //  #region和#endregion 是自定义折叠区域的一个宏定义方法，在代码较多时，
        //  我们通常将同类的代码归类，然后将其框在一对#region和#endregion之间。
        #region
        /// <summary>
        /// X序列
        /// </summary>
        public List<double> X { get; set; }
        /// <summary>
        /// Y序列
        /// </summary>
        public List<double> Y { get; set; }
        /// <summary>
        /// LINQ写法
        /// </summary>
        public double AvgX => X == null || X.Count() == 0 ? 0 : X.Average();
        public double AvgY => Y == null || Y.Count() == 0 ? 0 : Y.Average();
        /// <summary>
        /// 将原始集合进行变造输出		输出的不再是原始集合而是进行某种转换后得到的集合
        /// </summary>
        private List<double> x => X == null || X.Count() == 0 ? new List<double>() : X.Select(m => m - AvgX).ToList();
        private List<double> y => Y == null || Y.Count() == 0 ? new List<double>() : Y.Select(m => m - AvgY).ToList();
        /// <summary>
        /// 需要计算的系数a和b
        /// </summary>
        private double a { get; set; }
        private double b { get; set; }
        #endregion
        public void Compute()
        {
            double up = 0;
            double down = 0;
            for (int i = 0; i < X.Count(); i++)
            {
                up = x[i] * y[i];
                down = x[i] * x[i];
            }
            b = up / down;
            a = AvgY - AvgX * b;
        }
        public double Forecast(double x)
        {
            return a + b * x;
        }
    }
}
